Try Dead Channel V2, now with sound!
The code in this version is slightly less "interesting" than the first, but it incorporates the SHELLAM Method™ to install a machine language routine that switches between the graphics pages and clicks the speaker at random intervals to produce a more realistic visual effect.
The core trick of "printing" to the hi-res graphics page, which was adapted from the SHELLAM Method™ is still present in this version. But with the addition of a nice random number generator in machine language, along with the several orders of magnitude faster switching between hi-res pages, makes this demo more visually appealing.
It still takes about 5 minutes to setup, and to end it you must press RESET. The disk image attached has both the old and new versions.
1HGR2:HOME:POKE33,255:POKE41,2:?"300:A0 0 B9 54 C0 AD 30 C0 A5 4F 4A 26 4E 90 2 49 B4 85 4F 45 4E AA CA D0 FD 98 49 1 A8 10 E3 ND823G";:CALL-144:FORP=32TO95:POKE41,P:POKE49236+(P>63),0:HTAB1:FORX=1TO248:?CHR$(32+RND(1)*95);:NEXTX,P:CALL768
The code for this one is fairly straightforward. First we go into hi-res mode on page 2. This is primarily so we go into full graphics mode (no text window). We then issue a HOME, not to clear the screen, but to setup the base address for the ROM character out (COUT) routine to install our machine language routine. Since we are using the SHELLAM Method™, we must set the high byte of the COUT vector to the keyboard input buffer, so the POKE 41,2 does that. Before that we have a POKE 33,255 which sets the column width to the maximum possible. This is so that when we print our machine code entry string, the COUT routine will not try to wrap the line at the 40th column of the screen, since we are not printing to the screen but rather directly to memory. So this poke will trick COUT into thinking it's printing to a 255 column output device. Now that the COUT vector is setup, we can print out the string, which gets stuffed into the keyboard buffer, and then CALL -144 processes it. Normally, one does a POKE 72,0 before the CALL, but I realized that 72 always contains 0 when the program first starts so I left it out. The machine code is disassembled below.
Now that our machine code is installed, we go about "printing" random characters between ASCII 32 and 96 to the graphics screen (the normal display characters of letters, numbers, and punctuation; carriage returns and backspaces and such caused problems, so I don't attempt to randomly summon them). We do this in the same way we printed our machine code into the keyboard buffer, by setting the COUT buffer to a page within either graphics screen, successively writing out every page of graphics memory from the start of hi-res page #1 to the end of hi-res page #2, and you get to observe this in glorious realtime. P is looped from 32 to 95 ($20 to $5F); the POKE 41,P sets the page number in the COUT vector, and then we dumped 248 randomly generated characters into that page, being careful not to allow a carriage return to be invoke or else the low-byte of the COUT vector gets altered, and we need it to stay 0. Each iteration of P we flip the hi-res page switch so that we're always showing the page that's being drawn so we at least have something to watch while the visual is setting up. Page #1 will be displayed (49236) until P>63, i.e. when P=64 ($40) which is the beginning of hi-res page #2, then the P>63 will yield a 1, adding to 49236 to produce 49237, which is the soft-switch for page #2. The HTAB 1 ensures that we start printing to each new page at "column 1", i.e. it resets the horizontal cursor position stored in 36 ($24). Once the graphics pages are filled out with nonsense, we invoke our machine language program and go to town hammering soft switches, as follows:
LDY #0 ; Y-reg will oscillate between 0 and 1
LDA $C054,Y ; Display either hi-res page #1 (Y=0) or #2 (Y=1)
LDA $C030 ; click the speaker
LDA $4F ; Now we use KEYIN seed ($4E.4F) for our RNG routine
LSR ; I got this routine from the link below
ROL $4E
BCC +2 ; skip the EOR if the carry is clear
EOR #B4
STA $4F
EOR $4E ; at this point the Accumulator has our random number
TAX ; transfer the Accumulator to the X-register
DEX ; so we can use it for a quick delay
BNE -2 ; if X is not 0 then go back to DEX to decrement again
TYA ; now we need to toggle Y-register, so put it in Accumulator
EOR #01 ; this will toggle Y between 0/1
TAY ; transfer the result back to Y
BPL $302 ; this is effectively a "branch always" because the negative flag will always be zero here
This produces an effect much closer to a TV tuned to a dead channel.
I'll do a code breakdown of the first version later, as that uses more interesting tricks. I'm working on a 3rd version that does the same thing but uses a different method to install the machine language code. I may release that as V3 when it's ready. I'm trying to stick with 1 line for this one, and this current version uses exactly one line.